//
//  TapImageView.m
//  Custom_Weibo
//
//  Created by LEO on 12/16/15.
//  Copyright © 2015 Leo_Lei. All rights reserved.
//

#import "TapImageView.h"

@implementation TapImageView {
    UIImageView *_zoomImageView;    //  View for show the image
    UIScrollView *_scrollView;      //  View for enable the image to zoom in and out.
    
    CGFloat _dataSize;              //  The
    NSMutableData *_data;
    
    MBProgressHUD *_hud;
}

#pragma mark - INITIALIZATION_METHODS
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self tapImage];
        [self gifImageLogo];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self tapImage];
        [self gifImageLogo];
    }
    return self;
}

#pragma mark - GESTURE
- (void)tapImage {
    //  Make self interaction available.
    self.userInteractionEnabled = YES;
    
    //  Add a gesture to respond the event.
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(zoomIn)];
    [self addGestureRecognizer:tap];
}

#pragma mark - EXTRA_VIEW
- (void)gifImageLogo {
    _gifIconView = [[UIImageView alloc] initWithFrame:CGRectZero];
    _gifIconView.image = [UIImage imageNamed:@"timeline_gif"];
    [self addSubview:_gifIconView];
    
    _gifIconView.hidden = YES;
}

- (void)createScrollView {
    if (_scrollView == nil) {
        _scrollView = [[UIScrollView alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _scrollView.backgroundColor = [UIColor clearColor];
        
        //  Make the scroll indicator unvisible.
        _scrollView.showsHorizontalScrollIndicator = NO;
        _scrollView.showsVerticalScrollIndicator = NO;
        
        //  Set zoom mulitiple
        _scrollView.minimumZoomScale = 1.0;
        _scrollView.maximumZoomScale = 3.0;
        
        _scrollView.delegate = self;
        
        [self.window addSubview:_scrollView];
        
        _zoomImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        _zoomImageView.image = self.image;
        _zoomImageView.contentMode = UIViewContentModeScaleAspectFit;
        [_scrollView addSubview:_zoomImageView];
        
        /*  When we already got the 'zoom in' gesture, we also should make it
         can be 'zoom out'
         */
        UITapGestureRecognizer *zoomOut = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                  action:@selector(zoomOut)];
        [_scrollView addGestureRecognizer:zoomOut];
        
        /*  When we enter into image, we wanna save photos, add long press 
         gesture to response to that.
         */
        
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self
                                                                                                action:@selector(savePhotos:)];
        [_scrollView addGestureRecognizer:longPress];
    }
}

#pragma mark - IMAGE_ZOOM
- (void)zoomIn {
    if ([_delegate respondsToSelector:@selector(imageZoomIn:)]) {
        [_delegate imageZoomIn:self];
    }
    
    //  Create a scroll view to make image zoom impossible.
    [self createScrollView];
    
    CGRect imageFrame =[self convertRect:self.bounds toView:self.window];
    _zoomImageView.frame = imageFrame;
    
    //  When the image is zooming, set animation to let it see more smoothly.
    [UIView animateWithDuration:1 animations:^{
        _zoomImageView.frame = _scrollView.frame;
        _scrollView.backgroundColor = [UIColor blackColor];
    } completion:^(BOOL finished) {
        [self downloadClearImage];
    }];
}

- (void)zoomOut {
    if ([_delegate respondsToSelector:@selector(imageZoomOut:)]) {
        [_delegate imageZoomOut:self];
    }
    
    /*  Zoom out action also do the same, but the frame should be return
     back to its original size
     */
    CGRect imageFrame = [self convertRect:self.bounds toView:self.window];
    
    [UIView animateWithDuration:1 animations:^{
        _zoomImageView.frame = imageFrame;
        
        _scrollView.contentOffset = CGPointZero;
        _scrollView.backgroundColor = [UIColor clearColor];
    } completion:^(BOOL finished) {
        //  After return back, the object should be released.
        [_scrollView removeFromSuperview];
        _scrollView = nil;
        _zoomImageView = nil;
    }];
}

#pragma mark IMAGE_SAVE
- (void)savePhotos:(UILongPressGestureRecognizer *)longPress {
    if (longPress.state == UIGestureRecognizerStateBegan) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Tips"
                                                        message:@"Save Photo"
                                                       delegate:self
                                              cancelButtonTitle:@"NO"
                                              otherButtonTitles:@"YES", nil];
        [alert show];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == 1) {
        UIImage *image = _zoomImageView.image;
        UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    }
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.window animated:YES];
    hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark"]];
    hud.mode = MBProgressHUDModeCustomView;
    hud.labelText = @"Saved";
    [hud hide:YES afterDelay:1];
}

#pragma mark IMAGE_DOWNLOAD
- (void)downloadClearImage {
    if (_originImageUrl != nil) {
        _hud = [MBProgressHUD showHUDAddedTo:_scrollView animated:YES];
        _hud.mode = MBProgressHUDModeDeterminate;
        _hud.progress = 0.0;

        
        //  1)Get the image url for download.
        NSURL *url = [NSURL URLWithString:_originImageUrl];
        
        /*  2)Create session data task to download the image and set image on the
         image view.
         */
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:config
                                                              delegate:self
                                                         delegateQueue:[NSOperationQueue mainQueue]];
        NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url];
        
        //  3)Start downloading.
        [dataTask resume];
    }
}
#pragma mark - UISCROLLVIEW_DELEGATE
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return _zoomImageView;
}


#pragma mark - NSURLSESSIONDATA_DELEGATE
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    [_data appendData:data];
    CGFloat progress = _data.length / _dataSize;
    _hud.progress = progress;
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    NSHTTPURLResponse *responses = (NSHTTPURLResponse *)response;
    NSDictionary *headerFields = [responses allHeaderFields];
    NSString *length = [headerFields objectForKey:@"Content-Length"];
    _dataSize = [length floatValue];
    _data = [[NSMutableData alloc] init];
    completionHandler(NSURLSessionResponseAllow);
}



- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    [_hud hide:YES afterDelay:1];
    UIImage *image = [UIImage imageWithData:_data];
    _zoomImageView.image = image;
    
    CGFloat length = image.size.height / image.size.width * kScreenWidth;
    if (length > kScreenHeight) {
        [UIView animateWithDuration:1 animations:^{
            _zoomImageView.height = length;
            _scrollView.contentSize = CGSizeMake(kScreenWidth, length);
        }];
    }
    
    if (_gifIconView.hidden == NO) {
        [self showGif];
    }
};

#pragma mark - CUSTOM_METHODS
- (void)showGif {
    _zoomImageView.image = [UIImage sd_animatedGIFWithData:_data];
    
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)_data, NULL);
    size_t count = CGImageSourceGetCount(source);
    NSMutableArray *images = [[NSMutableArray alloc] init];
    for (NSInteger i = 0; i < count; i++) {
        CGImageRef imageCG = CGImageSourceCreateImageAtIndex(source, i, NULL);
        
        UIImage *imageUI = [UIImage imageWithCGImage:imageCG];
        [images addObject:imageUI];
        CGImageRelease(imageCG);
    }
    CFRelease(source);
    
    UIImage *animated = [UIImage animatedImageWithImages:images duration:images.count * 0.1];
    _zoomImageView.image = animated;
}
@end
